/**
 * @class 访问数据代理
 * @author DuskyHuang 圣子
*/

import { Proxy, decorators } from 'cfw';
import { interstellar, SceneGraph, TransformEnum } from 'const';
import { loadTransformType } from 'helpers';
import { UI, View } from 'notifications';
import { ICelestial, ITransformInfo } from 'prefabs';
import { LogProxy } from './log-proxy';
const { singleton } = decorators;

@singleton
export class VisitProxy extends Proxy {

    declare public static readonly instance: VisitProxy;
    private constructor() { super(); }

    public get center(): ICelestial | null { return this._center; }
    public get centerName(): celestial | null { return this._center?.node?.name as celestial ?? null; }
    public get inType(): into | null { return this._center?.cat as into ?? null; }
    public get transInfo(): Partial<ITransformInfo> { return this._transInfo; }
    public get transforming(): boolean { return this._transforming; }
    public get point(): pow10 { return this._point; }

    public static readonly LensOffsets = { BASE: 0.2, SUGGEST: 0.3, PLANET_SCOPE: 0.6 };
    public static readonly DETAIL_TOLERANCE: pow10 = 3;

    public visit(center: ICelestial): void {
        this._center = center;
        // Issue:01 Hack temp存在一定是SPC_2_SPC, Facing结束temp=null
        // 则在Facing的1秒钟内保持refer是from
        if (this._transInfo.stellar?.refers) {
            this._transInfo.stellar.refers.temp = null;
        }
        this.notify(Transform.FACE_OVER);
    }

    protected onClickVisit(name: celestial, into: into, point: pow10 = null): void {
        if (name === this._center?.node?.name) return;
        else {
            this._point = point;
            this._transforming = true;
            this._transInfo.name = name;
            this._transInfo.into = into;
            this._transInfo.from = this._center;
            this._transInfo.target = this._transInfo.mediator = null;
            this._transInfo.stellar = null;
            loadTransformType(this._transInfo);
            if (LogProxy.PRINT_TRANS) {
                console.info('[Trans]:', TransformEnum[this._transInfo.transEnum], into, name);
            }
            this.notify(Transform.ZOOM_START);
        }
    }

    public get inSolar(): boolean { return this.centerName === 'Sun'; }
    public get inPlanetary(): boolean { return ['planet', 'dwarf', 'minor', 'comet', 'belts'].contains(this.inType); }
    public get inPlanet(): boolean { return this.inType === 'planet' }
    public get inComet(): boolean { return this.inType === 'comet' }
    public get inSatellite(): boolean { return this.inType === 'satellite'; }

    public get inStellar(): boolean { return interstellar.contains(this.inType) && this.centerName !== 'Sun'; }
    public get inStar(): boolean { return this.inType === 'star' && this.centerName !== 'Sun'; }
    public get inCluster(): boolean { return this.inType === 'cluster'; }
    public get inNebula(): boolean { return this.inType === 'nebula'; }
    public get inLocalGalactic(): boolean { return this.inType === 'galaxy' && this.center?.node?.parent?.name === Local.GALAXIES; }
    public get inVirgoGalactic(): boolean { return this.inType === 'galaxy' && this.center?.node?.parent?.name === Virgo.GALAXIES; }
    public get inBlackhole(): boolean { return this.inType === 'blackhole'; }

    protected init(): void {
        this.on(UI.VISIT, this.onClickVisit);
        this.on(Transform.VISIT_OVER, this._onVisitOver, 99);
    }

    private _onVisitOver(): void {
        this._transforming = false;
        if (this._transInfo.stellar) {
            this._transInfo.stellar.refers.from =
                this._transInfo.stellar.refers.to;
        }
    }

    private _center: ICelestial = null;
    private _transInfo: Partial<ITransformInfo> = {};
    private _transforming: boolean = false;
    private _point: pow10 = null;
}

const { Transform } = View;
const { Local, Virgo } = SceneGraph;

export const visit = VisitProxy.instance;